package cn.com.netty.nettypushmessage.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * Netty Push Message Server
 */
@Component
public class NettyPushMessageServer {
    // TODO: define logger
    private static final Logger logger = LoggerFactory.getLogger(NettyPushMessageServer.class);

    @Value("${server.port}")
    public Integer port;

    /**
     * init
     */
    private void init() {
        logger.info("Now is starting WebSocket Server...");
        /**
         * { bossGroup, workerGroup } thread
         */
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup);
            bootstrap.option(ChannelOption.SO_BACKLOG, 128);
            bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
            bootstrap.channel(NioServerSocketChannel.class);
            bootstrap.childHandler(new NettyPushMessageChannelInitializer());
            Channel channel = bootstrap.bind(port).sync().channel();
            logger.info("WebSocket server starts successfully: " + channel);
            channel.closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
            logger.info("Runtime error: " + e);
        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
            logger.info("WebSocket server is closed.");
        }
    }

    // @PostConstruct()
    public void start(){
        //需要开启一个新的线程来执行netty server 服务器
        new Thread(new Runnable() {
            @Override
            public void run() {
                init();
            }
        }).start();
    }
}